package com.gwt.material.client.user.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.gwt.boot.exception.BusinessException;
import com.gwt.boot.tools.ApiTools;
import com.gwt.boot.tools.UrlTools;
import com.gwt.cloud.constant.ApiResultEnum;
import com.gwt.material.client.user.dao.WechatUserMapper;
import com.gwt.material.client.user.dto.WechatAuthDTO;
import com.gwt.material.client.user.dto.WechatUserDTO;
import com.gwt.material.client.user.po.User;
import com.gwt.material.client.user.po.UserSourceRel;
import com.gwt.material.client.user.po.WechatUser;
import com.gwt.material.client.user.service.WechatUserService;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import static com.gwt.material.client.user.po.table.UserTableDef.USER;
import static com.gwt.material.client.user.po.table.WechatUserTableDef.WECHAT_USER;


@Service
@Log4j2
public class WechatUserServiceImpl extends ServiceImpl<WechatUserMapper, WechatUser> implements WechatUserService {

    @Value("${wechat.appid}")
    private String appId;

    @Value("${wechat.appsecret}")
    private String appSecret;

    @Value("${wechat.auth.url}")
    private String weCatAuthUrl;

    @Value("${wechat.redirect-uri}")
    private String redirectUri;

    @Value("${wechat.qrcode.url}")
    private String weCatQrCodeUrl;

    @Override
    public WechatUserDTO getWechatUserByOpenId(String openId) {
        QueryWrapper queryWrapper = QueryWrapper.create()
                .from(WechatUser.class)
                .select(WECHAT_USER.ALL_COLUMNS)
                .leftJoin(UserSourceRel.class).on(WechatUser :: getId, UserSourceRel :: getRelId)
                .leftJoin(User.class).on(UserSourceRel :: getUserId, User :: getId)
                .select(USER.ID.as("userId"))
                .where(WechatUser :: getOpenId).eq(openId);
        return this.getOneAs(queryWrapper, WechatUserDTO.class);
    }

    @Override
    public WechatUser createWechatUser(WechatAuthDTO wechatAuthDTO) {
        WechatUser wechatUser = new WechatUser();
        wechatUser.setOpenId(wechatAuthDTO.getOpenid());
        wechatUser.setUnionId(wechatAuthDTO.getUnionid());
        this.save(wechatUser);
        return wechatUser;
    }

    @Override
    public String wechatQrCode() {
        String state = UUID.randomUUID().toString();
        try {
            String qrCodeUrl = weCatQrCodeUrl + "?" +
                    "appid=" + appId +
                    "&redirect_uri=" + UrlTools.urlEncode(redirectUri) +
                    "&response_type=code&scope=snsapi_login&state=" + state +
                    "#wechat_redirect";
            return qrCodeUrl;
        } catch (UnsupportedEncodingException e) {
            throw new BusinessException(-1, "二维码生成失败！");
        }
    }

    @Override
    public WechatAuthDTO getWechatToken(String code, String state) {
        log.debug("code:" + code);
        log.debug("state:" + state);
        if (StringUtils.hasText(code)){
            Map<String, String> params = new HashMap<>();
            params.put("appid", appId);
            params.put("secret", appSecret);
            params.put("code", code);
            params.put("grant_type", "authorization_code");
            WechatAuthDTO wechatAuthDTO = ApiTools.sendGetRequest(weCatAuthUrl, params, WechatAuthDTO.class);
            log.debug("result:" + JSONObject.toJSONString(wechatAuthDTO));
            if (wechatAuthDTO != null && wechatAuthDTO.getOpenid() != null && wechatAuthDTO.getRefresh_token() != null && wechatAuthDTO.getAccess_token() != null){
                return wechatAuthDTO;
            }
            throw new BusinessException(ApiResultEnum.FAIL.getStatus(), "获取用户授权信息失败，请稍后再试！");
        }else {
            throw new BusinessException(ApiResultEnum.FAIL.getStatus(), "用户拒绝授权！");
        }
    }
}
